package core.modules.developer.entity;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;

public class Generator {

	public static final String FTL_PATH = "developer/generator/ftl/";// 模板路径

	public static List<Table> getTablesInfo(SqlSession sqlSession, String tableName) throws Exception {
		List<Table> t = getTablesInfo(sqlSession.getConnection(), tableName);
		sqlSession.close();
		return t;
	}

	public static List<Table> getTablesInfo(Connection con, String tableName) throws Exception {
		tableName = tableName == null ? "%" : "%"+tableName+"%";
		DatabaseMetaData dbmd = con.getMetaData();
		String[] types = { "TABLE" };
		ResultSet rs = dbmd.getTables(null, null, tableName, types);
		List<Table> tables = new ArrayList<Table>();
		while (rs.next()) {
			String name = rs.getString("TABLE_NAME"); // 表名
			String remarks = rs.getString("REMARKS"); // 表备注
			Table table = new Table(name, remarks);
			tables.add(table);
		}
		rs.close();
		for (Table table : tables) {
			rs = dbmd.getColumns(null, null, table.getName(), null);
			while (rs.next()) {
				String name = rs.getString("COLUMN_NAME");// 列名称
				String remarks = rs.getString("REMARKS"); // 列描述
				int dataType = rs.getInt("DATA_TYPE");
				int nullable = rs.getInt("NULLABLE");
				int charLength = rs.getInt("CHAR_OCTET_LENGTH");
				table.getColumns().add(new Column(name, remarks, dataType, nullable, charLength));
				if (java.sql.Types.TIMESTAMP == dataType || java.sql.Types.TIME == dataType
						|| java.sql.Types.DATE == dataType) {
					table.setDateFlag("1");
				}
			}
			rs.close();
		}
		con.close();
		return tables;
	}

	public static void generate(Configuration cfg, Table table, String floder) throws TemplateNotFoundException,
			MalformedTemplateNameException, ParseException, IOException, TemplateException {
		String core = floder + "/core文件/" + table.getModule() + "/";
		String controller = floder + "/controller文件/" + table.getModule() + "/";
		String ftl = floder + "/页面ftl/" + table.getModule() + "/" + table.getJavaNameUnCapFirst() + "/";

		generateMapper(cfg, table, core + "mappings/");
		generateEntity(cfg, table, core + "entity/");
		generateDao(cfg, table, core + "dao/");
		generateService(cfg, table, core + "service/");
		generateController(cfg, table, controller);
		generateList(cfg, table, ftl);
		generateForm(cfg, table, ftl);
	}

	public static void generateMapper(Configuration cfg, Table table, String floder) throws TemplateNotFoundException,
			MalformedTemplateNameException, ParseException, IOException, TemplateException {
		generateCommon(cfg, table, FTL_PATH + "Mapper.xml", floder, "Mapper.xml");
	}

	public static void generateEntity(Configuration cfg, Table table, String floder) throws TemplateNotFoundException,
			MalformedTemplateNameException, ParseException, IOException, TemplateException {
		generateCommon(cfg, table, FTL_PATH + "Entity.java", floder, ".java");
	}

	public static void generateDao(Configuration cfg, Table table, String floder) throws TemplateNotFoundException,
			MalformedTemplateNameException, ParseException, IOException, TemplateException {
		generateCommon(cfg, table, FTL_PATH + "Dao.java", floder, "Dao.java");
	}

	public static void generateService(Configuration cfg, Table table, String floder) throws TemplateNotFoundException,
			MalformedTemplateNameException, ParseException, IOException, TemplateException {
		generateCommon(cfg, table, FTL_PATH + "Service.java", floder, "Service.java");
	}

	public static void generateController(Configuration cfg, Table table, String floder)
			throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException,
			TemplateException {
		generateCommon(cfg, table, FTL_PATH + "Controller.java", floder, "Controller.java");
	}

	public static void generateList(Configuration cfg, Table table, String floder) throws TemplateNotFoundException,
			MalformedTemplateNameException, ParseException, IOException, TemplateException {
		generateCommon(cfg, table, FTL_PATH + "List.ftl", floder, "List.ftl");
	}

	public static void generateForm(Configuration cfg, Table table, String floder) throws TemplateNotFoundException,
			MalformedTemplateNameException, ParseException, IOException, TemplateException {
		generateCommon(cfg, table, FTL_PATH + "Form.ftl", floder, "Form.ftl");
	}

	public static void generateCommon(Configuration cfg, Table table, String templateFile, String floder,
			String typename) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException,
			IOException, TemplateException {
		Template temp = cfg.getTemplate(templateFile);

		String fileName = table.getJavaNameCapFirst() + typename;
		File folder = new File(floder);
		if (!folder.exists()) {
			folder.mkdirs();
		}

		File file = new File(floder + fileName);
		FileWriter fw = new FileWriter(file);
		BufferedWriter bw = new BufferedWriter(fw);
		Map<String, Object> root = new HashMap<String, Object>();
		root.put("table", table);
		temp.process(root, bw);
		bw.flush();
		fw.close();
	}
}
